﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

using ComponentFactory.Krypton.Toolkit;
using System.Net;
using System.Net.Sockets;
using XQMSTicket.Reports;

namespace XQMSTicket
{
    public partial class frmXQMSTicket : ComponentFactory.Krypton.Toolkit.KryptonForm
    {
        public frmXQMSTicket()
        {
            InitializeComponent();

            // Hook into the click events on the header buttons
            kryptonHeaderGroup1.ButtonSpecs[0].Click += new EventHandler(OnLeftRight);
            //kryptonHeaderGroup3.ButtonSpecs[0].Click += new EventHandler(OnUpDown);
        }

        #region GUI Related
        private int _widthLeftRight;
        //private int _heightUpDown;

        private void OnLeftRight(object sender, EventArgs e)
        {
            // (1) Suspend changes until all splitter properties have been updated
            kryptonSplitContainer1.SuspendLayout();   

           // (2) Is the left header group currently expanded?
           if (kryptonSplitContainer1.FixedPanel == FixedPanel.None)
           {
               // (3) Make the left panel fixed in size
               kryptonSplitContainer1.FixedPanel = FixedPanel.Panel1;
               kryptonSplitContainer1.IsSplitterFixed = true; 

               // (4) Remember the current height of the header group      
               _widthLeftRight = kryptonHeaderGroup1.Width;

               // (5) Find the new width to use for the header group
               int newWidth = kryptonHeaderGroup1.PreferredSize.Height;
               
               // (6) Make the header group fixed just as the new height
               kryptonSplitContainer1.Panel1MinSize = newWidth;
               kryptonSplitContainer1.SplitterDistance = newWidth;

               // (7) Change header to be vertical and button to near edge      
               kryptonHeaderGroup1.HeaderPositionPrimary = VisualOrientation.Right;      
               kryptonHeaderGroup1.ButtonSpecs[0].Edge = PaletteRelativeEdgeAlign.Near;   
           }   
           else   
           {
               // Make the bottom panel not-fixed in size anymore
               kryptonSplitContainer1.FixedPanel = FixedPanel.None;
               kryptonSplitContainer1.IsSplitterFixed = false;

               // Put back the minimize size to the original
               kryptonSplitContainer1.Panel1MinSize = 100;
              
               // Calculate the correct splitter we want to put back
               kryptonSplitContainer1.SplitterDistance = _widthLeftRight;
              
               // Change header to be horizontal and button to far edge
               kryptonHeaderGroup1.HeaderPositionPrimary = VisualOrientation.Top;
               kryptonHeaderGroup1.ButtonSpecs[0].Edge = PaletteRelativeEdgeAlign.Far;   
           
           }         

            kryptonSplitContainer1.ResumeLayout(); 
        }

        private void OnUpDown(object sender, EventArgs e)
        {
            //// (1) Is the bottom right header group currently expanded?
            //if (kryptonSplitContainer2.FixedPanel == FixedPanel.None)
            //{
            //    // (2) Make the bottom panel fixed in size
            //    kryptonSplitContainer2.FixedPanel = FixedPanel.Panel2;
            //    kryptonSplitContainer2.IsSplitterFixed = true;

            //    // (3) Remember the current height of the header group
            //    _heightUpDown = kryptonHeaderGroup3.Height;

            //    // (4) Find the new height to use for the header group
            //    int newHeight = kryptonHeaderGroup3.PreferredSize.Height;

            //    // (5) Make the header group fixed just as the new height
            //    kryptonSplitContainer2.Panel2MinSize = newHeight;
            //    kryptonSplitContainer2.SplitterDistance = kryptonSplitContainer2.Height;
            //}
            //else
            //{
            //    // Make the bottom panel not-fixed in size anymore
            //    kryptonSplitContainer2.FixedPanel = FixedPanel.None;
            //    kryptonSplitContainer2.IsSplitterFixed = false;

            //    // Put back the minimum size to the original
            //    kryptonSplitContainer2.Panel2MinSize = 100;

            //    // Calculate the correct splitter we want to put back
            //    kryptonSplitContainer2.SplitterDistance =
            //       kryptonSplitContainer2.Height - _heightUpDown - kryptonSplitContainer2.SplitterWidth;
            //}
        }
        #endregion GUI Related

        #region Client Server
        TcpClient client;
        private void Connect(String server)
        {
            try
            {
                // Create a TcpClient.
                // Note, for this client to work you need to have a TcpServer 
                // connected to the same address as specified by the server, port
                // combination.

                Int32 port = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["ServerPort"]);

                server = System.Configuration.ConfigurationManager.AppSettings["ServerName"];
                client = new TcpClient(server, port);
            }
            catch (ArgumentNullException e)
            {
                //lbxQueue.Items.Add("ArgumentNullException: " + e);
                MessageBox.Show("ArgumentNullException: " + e);
            }
            catch (SocketException e)
            {
                MessageBox.Show("SocketException: " + e);
            }
        }

        private void SendData(TcpClient client, string message)
        {
            try
            {
                // Translate the passed message into ASCII and store it as a Byte array.
                Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);

                // Get a client stream for reading and writing.
                //  Stream stream = client.GetStream();

                NetworkStream stream = client.GetStream();


                // Send the message to the connected TcpServer. 
                stream.Write(data, 0, data.Length);

                //lbxQueue.Items.Add("S: " + message);

                string responseData = ReceiveData(data, stream);
                ServerDataProcess(message, responseData);

                stream.Close();
                client.Close();
            }
            catch (ArgumentNullException e)
            {
                //lbxQueue.Items.Add("ArgumentNullException: " + e);
                MessageBox.Show("ArgumentNullException: " + e);
            }
            catch (SocketException e)
            {
                MessageBox.Show("SocketException: " + e);
            }
        }

        private string ReceiveData(Byte[] data, NetworkStream stream)
        {
            // Receive the TcpServer.response.

            // Buffer to store the response bytes.
            data = new Byte[256];

            // String to store the response ASCII representation.
            String responseData = String.Empty;

            // Read the first batch of the TcpServer response bytes.
            Int32 bytes = stream.Read(data, 0, data.Length);
            responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
            
            //lbxQueue.Items.Add("R: " + responseData);
            //lbxQueue.Items.Add(System.DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + " -----------------------------------------------------");
            //lbxQueue.SelectedIndex = lbxQueue.Items.Count - 1;
            //lbxQueue.SelectedIndex = -1;

            return responseData;

        }

        private void ServerDataProcess(string message, string responseData)
        {
            string[] messageSplit = message.Split(' ');
            string cmdID = messageSplit[0];
            string ClientQueCatCode = messageSplit[1];
            string ClientQueCatNo = messageSplit[2];

            switch (cmdID)
            {
                case "-": //Dequeue
                    if (responseData != "0")
                    {
                        //lblQueueNo.Text = responseData.PadLeft(4, '0');
                        TimeRecord(responseData);
                    }
                    //else
                    //    lblQueueNo.Text = "No Queue";
                    break;
            }
        }
        #endregion Client Server
        private void TimeRecord(string queNo)
        {
            DataRow dr = DSMain.Tables["DTTime"].NewRow();

            dr["timeCatCode"] = "D";
            dr["timeExec"] = System.DateTime.Now;
            dr["queNo"] = queNo.PadLeft(4, '0');

            DSMain.Tables["DTTime"].Rows.Add(dr);

            //DGVMain.FirstDisplayedCell = DGVMain.Rows[DGVMain.Rows.Count - 1].Cells[0];
        }
        #region Database Related

#endregion Database Related

        #region System Related
        //XQMSServiceClient client = new XQMSServiceClient();

        private void SystemStartUp()
        {
            pctAd.ImageLocation = System.Environment.CurrentDirectory + "\\antri.jpg";
            pctAd.SizeMode = PictureBoxSizeMode.CenterImage;

            Connect(System.Configuration.ConfigurationManager.AppSettings["ServerName"]);
            SendData(client, "Ticketing System Online");
        }
        #endregion System Related

        #region Windows Forms
        private void frmXQMSTicket_Load(object sender, EventArgs e)
        {
            SystemStartUp();
        }

        private void btnCSO_Click(object sender, EventArgs e)
        {
            String queCategory = "CSO";

            Connect(System.Configuration.ConfigurationManager.AppSettings["ServerName"]);
            SendData(client, "+" + " " + queCategory + " " + "Ticket");

            SetQueueNo(queCategory);
            
            int count = DSMain.Tables["DTQueue"].Rows.Count;
            PrintReport(queCategory, DSMain.Tables["DTQueue"].Rows[count - 1]["queNo"].ToString());
        }

        private void btnTeller_Click(object sender, EventArgs e)
        {
            String queCategory = "Teller";

            Connect(System.Configuration.ConfigurationManager.AppSettings["ServerName"]);
            SendData(client, "+" + " " + queCategory + " " + "Ticket");

            SetQueueNo(queCategory);

            int count = DSMain.Tables["DTQueue"].Rows.Count;
            PrintReport(queCategory, DSMain.Tables["DTQueue"].Rows[count - 1]["queNo"].ToString());
        }
        #endregion Windows Forms

        private void SetQueueNo(string queCategory)
        {
            string[] queCat = System.Configuration.ConfigurationManager.AppSettings["QueCat"].Split(';');
            string[] queStartNo = System.Configuration.ConfigurationManager.AppSettings["QueCatStartNo"].Split(';');

            for (int i = 0; i < queCat.Length; i++)
            {
                if (queCat[i] == queCategory) {
                    DataRow[] arrDR = DSMain.Tables["DTQueue"].Select("queCat = '" + queCategory + "'");
                    DataRow dr = DSMain.Tables["DTQueue"].NewRow();
                    int count = arrDR.Length;
                    if (count <= 0)
                    {
                        dr["queCat"] = queCategory;
                        dr["queNo"] = queStartNo[i];
                    }
                    else
                    {
                        dr["queCat"] = queCategory;

                        int queNo = Convert.ToInt16(arrDR[arrDR.Length - 1][1]) + 1;
                        dr["queNo"] = queNo;
                    }

                    DSMain.Tables["DTQueue"].Rows.Add(dr);
                }
            }
        }

        private void PrintReport(string queueCat, string queueNo)
        {
            rptStrukQueue rptStruk = new rptStrukQueue();
            rptStruk.QueueCat = queueCat;
            rptStruk.QueueNo = queueNo.PadLeft(4, '0');
            rptStruk.Show();
        }
    }
}
